﻿#pragma once
#include "Comm.h"
#include "Buffer.h"
#ifdef COMM_MSVC

namespace COMM
{
	class COMM_API ServiceTask
	{
	public:
		virtual ~ServiceTask(){}

		///服务初始化通知
		///@remark 完成后需及时返回, 不能长时间阻塞
		virtual bool OnInit(int argc, char** argv){return true;}

		///服务启动通知
		///@remark 服务启动阻塞执行此过程, 直至服务停止/关闭
		virtual void OnStart(){}

		///服务停止通知
		///@remark OnStart结束返回, 服务变为停止状态
		virtual void OnStop(){}

		///服务暂停通知
		///@remark OnStart暂停执行, 服务变为暂停状态
		virtual void OnPause(){}

		///被暂停的服务恢复通知
		///@remark OnStart恢复执行, 服务变为恢复状态
		virtual void OnContinue(){}

		///服务被强制关闭通知
		///@remark 通常是OS关闭时发生
		virtual void OnShutdown(){}
	};

	class COMM_API NTService
	{
	public:
		enum ServiceStartupType
		{
			SST_DISABLED=0,
			SST_AUTO_START=1,
			SST_MANUAL_START=2
		};

		NTService(const char* name);
		~NTService();
		bool IsInstalled();
		bool Install(const char* displayName, ServiceStartupType type);
		bool UnInstall();
		bool SetStartupType(ServiceStartupType type);
		bool UpdateDesc(const char* desc);
		bool Start(int argc=0, const char** argv=0);
		bool Stop();
		bool GetCurrentStatus(DWORD& dwCurrentState);

		bool Main(ServiceTask* service,
			bool canStop=true,
			bool canShutdown=true,
			bool canPausecontinue=false,
			int waitTimeoutMs=1000);
	private:
		String m_name;
	};


	// CommNTService
	//
	class COMM_API CommNTService
	{
	public:
		CommNTService(const char* serviceName, const char* serviceDisplay, const char* serviceDescription, NTService::ServiceStartupType serviceType,
			const char* runCommandPath, bool restartWhenCrash=false,bool runAsUserSession=false);
		// argv[1]: 
		// -i: Install
		// -u: Uninstall
		// -r: Start
		// -s: Stop
		// -t: Status
		// -d: Debug(run command directly)
		int Main(int argc, char* argv[]);

	private:
		String m_serviceName;
		String m_serviceDisplay;
		String m_serviceDescription;
		NTService::ServiceStartupType m_serviceType;
		String m_runCommandPath;
		bool m_restartWhenCrash;
		bool m_runAsUserSession;
		NTService m_service;

	};

	
}

#endif